package com.elink.enginerring.interceptor;

import java.io.PrintWriter;
import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.springframework.http.MediaType;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.alibaba.fastjson.JSONObject;
import com.elink.enginerring.common.Constant;
import com.elink.enginerring.common.ErrorType;
import com.elink.enginerring.interceptor.authority.For;
import com.elink.enginerring.interceptor.authority.UserType;
import com.elink.enginerring.user.entity.User;
import com.elink.enginerring.util.JSONUtil;
/**
 * 接口安全控制,身份验证
 * @author Rick
 *
 */
public class RoleInterceptor extends HandlerInterceptorAdapter {
	
	@Override
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		request.setCharacterEncoding("UTF-8");
		System.out.println("=================================="+request.getRequestURL());
		System.out.println("=================================="+request.getRemoteAddr());
		if(Except.isExcept(request.getRequestURL().toString())){
			return true;
		}
		Method method=null;
		try {
			HandlerMethod handlerMethod = (HandlerMethod) handler;
			method = handlerMethod.getMethod();
		} catch (ClassCastException e) {
			Logger logger=Logger.getLogger(this.getClass());
			logger.error("illegal request:"+request.getRequestURL(),e);
			return false;
		}

		UserType[] types = parseGetTypes(method);
		//身份验证并进行处理
		boolean isContinue=true;
		if (types != null) {
			if(types.length==1){        //只支持一种用户,必须满足对应的验证条件
				UserType type=types[0];
				switch (type) {
				case WEBSERVER_USER:
					if(!User(request)){
						System.out.println("web_user interceptor......");
						
//						String contentType=request.getHeader("Content-Type");
						if(request.getRequestURL().toString().endsWith(".htm")){
							response.sendRedirect(request.getContextPath()+"/reLogin.jsp");
						}else {
							response.setCharacterEncoding(Constant.ENCODING);
							response.setContentType(MediaType.APPLICATION_JSON_VALUE);
							PrintWriter out = response.getWriter();
							out.print(JSONObject.toJSONString(JSONUtil.getJSON(ErrorType.NEED_LOGIN)));
						}
						isContinue=false;
					}
					break;
				default:
					break;
				}
			}else {                    		//支持多种用户,满足其一即可
				isContinue=false;           //默认拦截
				for(UserType type:types){
					if(!isContinue){
						switch (type) {
						case WEBSERVER_USER:
							if(User(request)){
								isContinue=true;
							}
							break;
						default:
							break;
						}
					}else {
						break;
					}
				}
				if(!isContinue){
					if(request.getRequestURL().toString().endsWith(".htm")){
						response.sendRedirect(request.getContextPath()+"/reLogin.jsp");
					}else {
						response.setCharacterEncoding(Constant.ENCODING);
						response.setContentType(MediaType.APPLICATION_JSON_VALUE);
						PrintWriter out = response.getWriter();
						out.print(JSONObject.toJSONString(JSONUtil.getJSON(ErrorType.NEED_LOGIN)));
					}
				}
			}
		}
		System.out.println("==================================");
		return isContinue;
	}
	
	/**
	 * 根据方法获取到方法上的For注解的UserType
	 * @param method
	 * @return
	 */
	private UserType[] parseGetTypes(Method method){
		UserType[] types = null;
		//1.方法上的For注解
		For f = method.getAnnotation(For.class);
		if (f != null) {
			System.out.println("method anotation");
			types = f.user();
		}
		//2.如果方法上没，则判断类上有没有(他们之间的关系是覆盖关系,就近原则)
		if (types == null) {
			For classFor = method.getDeclaringClass().getAnnotation(For.class);
			if (classFor != null) {
				System.out.println("class anotation");
				types = classFor.user();
			}
		}
		return types;
	}
	

	/**
	 * 验证后台用户是否具有访问资格(session中是否有user)
	 * @param request
	 * @return true代表有权限
	 */
	private boolean User(HttpServletRequest request){
		HttpSession session=request.getSession();
		User su=(User) session.getAttribute(Constant.su_in_session);
		if(su==null){
			return false;
		}
		return true;
	}
	
	/**
	 * 捕获异常
	 */
	@Override
	public void afterCompletion(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		if(ex!=null){
			//1.记录日志
			HandlerMethod handlerMethod = (HandlerMethod) handler;
			Method method = handlerMethod.getMethod();
			Logger logger=Logger.getLogger(method.getClass());
			logger.error(ex.getMessage());
			
			UserType[] types = parseGetTypes(method);
			//2.向请求者返回错误信息
			if (types != null && types.length>0) {
				UserType type=types[0];
				switch (type) {
				case APP_USER:
					//app请求,返回错误json信息
				case WEBSERVER_USER:
					response.setCharacterEncoding(Constant.ENCODING);
					response.setContentType(MediaType.APPLICATION_JSON_VALUE);
					PrintWriter out = response.getWriter();
					out.print(JSONObject.toJSONString(JSONUtil.getJSON(ErrorType.SERVER_ERROR)));
					//web请求,跳转到错误页面
//					response.sendRedirect(request.getContextPath()+"/error.jsp");
					break;
				default:
					response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "服务器出错");
					break;
				}
			}else {
				response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "服务器出错");
			}
		}
	}
}